#!/usr/bin/python

#This file is for reading GridFloat data from http://seamless.usgs.gov and turning it into valid data for my ray tracer
#It takes two files of the same name, an .flt and .hdr file, then outputs a single .hf file. 

import sys
import Numeric
import array
if(len(sys.argv) < 4):
 print "usage ", sys.argv[0], " <file name without extension> <minz> <maxz>"
else:
 #save the arguments
 minz = float(sys.argv[2])
 maxz = float(sys.argv[3])
 #read the header data
 header_file_name = sys.argv[1] + ".hdr"
 data_file_name = sys.argv[1] + ".flt"
 header_file = open(header_file_name, 'r')
 data_file = open(data_file_name, 'rb')
 #expect the following from the file:
 #ncols    947
 header_line = header_file.readline()
 vals = header_line.split()
 if(vals[0] != "ncols"):
  print "expected 'ncols' at line 1. Exiting"
  exit()
 else:
  ncols = int(vals[1])
 #expect the following from the file:
 #nrows    450
 header_line = header_file.readline()
 vals = header_line.split()
 if(vals[0] != "nrows"):
  print "expected 'nrows' at line 2. Exiting"
  exit()
 else:
  nrows = int(vals[1])
 print "Number of columns: ", ncols
 print "Number of rows: ", nrows
 #get all the data out of the data file
 binvalues = array.array('f')
 binvalues.read(data_file, nrows * ncols)
 data = Numeric.array(binvalues, typecode=Numeric.Float)
 data = Numeric.reshape(data, (nrows, ncols))
 #now find the min and max z values in the data file
 data_minz = data[0][0]
 data_maxz = data[0][0]
 for i in range(1, nrows):
  for j in range(1, ncols):
   val = data[i][j]
   if(val < data_minz): data_minz = val
   if(val > data_maxz): data_maxz = val
 print "Data Minz: ", data_minz
 print "Data Maxz: ", data_maxz
 #Now scale the file data to fit within the given bounds
 scale = maxz / data_maxz
 last_val = data[0][0]
 for i in range(0, nrows-1):
  for j in range(0, ncols-1):
   try:
    val = data[i][j]
    val = val - data_minz
    val = val * scale
    val = val + minz
    data[i][j] = val
    if(val > maxz or val < minz):
     print val, " "
    if(abs(val - last_val) > 0.5):
     print last_val
    last_val = val
   except:
    print "error writing to data array at i: ", i," j: ", j
 #Now write out the data to the file in the format that Kinyk expects
 #nx ny minz maxz <data>
 height_file_name = sys.argv[1] + ".hf"
 height_file = open(height_file_name, 'wb')
 height_file.write(str(ncols - 1))
 height_file.write(" ")
 height_file.write(str(nrows - 1))
 height_file.write(" ")
 height_file.write(str(minz))
 height_file.write(" ")
 height_file.write(str(maxz))
 height_file.write(" ")
 #write all the data in one huge block
 outvalues = array.array('f')
 outvalues.fromlist( data.flat.tolist() )
 outvalues.tofile(height_file)
 height_file.close()
 print "Done writing information to file ", height_file_name
